package com.wanghua.spring.filter;

import java.io.IOException;

import com.wanghua.spring.filter.exception.AccountException;
import com.wanghua.spring.filter.exception.BusinessException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * Filter 与 Listener 都属于 Servlet 的规范。
 * 异常捕捉 Filter。
 * 如果在 chain.doFilter(request,response) 上加一句 try...catch 语句，就能捕捉 Servlet 中抛出的可预料的与不可预料的异常。
 */
public class ExceptionHandlerFilter implements Filter {
    public void init(FilterConfig arg0) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            chain.doFilter(request, response);  //执行下一个 Filter 或 Servlet。
        } catch (Exception e) {

            //循环，直到找到根异常为止。
            Throwable rootCause = e;
            while (rootCause.getCause() != null) {
                rootCause = rootCause.getCause();
            }

            String message = rootCause.getMessage();
            message = message == null ? "异常：" + rootCause.getClass().getName() : message;

            request.setAttribute("message", message);
            request.setAttribute("e", e);

            if (rootCause instanceof AccountException) {
                request.getRequestDispatcher("/filter/exception/accountException.jsp").forward(request, response);
            } else if (rootCause instanceof BusinessException) {
                request.getRequestDispatcher("/filter/exception/businessException.jsp").forward(request, response);
            } else {
                request.getRequestDispatcher("/filter/exception/exception.jsp").forward(request, response);
            }
        }
    }

    public void destroy() {
    }
}
